package com.tango.tangoapp.arealearning;

import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.atap.tangoservice.Tango;
import com.google.atap.tangoservice.TangoAreaDescriptionMetaData;
import com.google.atap.tangoservice.TangoConfig;

import com.google.atap.tangoservice.TangoCoordinateFramePair;
import com.google.atap.tangoservice.TangoErrorException;
import com.google.atap.tangoservice.TangoEvent;
import com.google.atap.tangoservice.TangoInvalidException;
import com.google.atap.tangoservice.TangoOutOfDateException;
import com.google.atap.tangoservice.TangoPointCloudData;
import com.google.atap.tangoservice.TangoPoseData;
import com.google.atap.tangoservice.TangoXyzIjData;
import com.tango.tangoapp.R;

import java.util.ArrayList;

/**
 * Created by DELL on 2017/7/18.
 */

public class AreaLearningActivity extends Activity implements
        SetAdfNameDialog.CallbackListener,
        SaveAdfTask.SaveAdfListener{
    private static final String TAG=AreaLearningActivity.class.getSimpleName();
    private Tango mTango;
    private TangoConfig mConfig;
    private TextView mUuidTextView;
    private TextView mLocationTextView;

    private Button mSaveAdfButton;

    private SaveAdfTask mSaveAdfTask;

    private final Object mSharedLock=new Object();

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.area_learning_activity);
    }

    @Override
    protected void onResume(){
        super.onResume();

        mTango=new Tango(AreaLearningActivity.this, new Runnable() {
            @Override
            public void run() {
                synchronized (AreaLearningActivity.this) {
                    try {
                        mConfig = setTangoConfig(mTango);
                        mTango.connect(mConfig);
                        startupTango();
                    } catch (TangoOutOfDateException e) {
                        Log.e(TAG, getString(R.string.exception_out_of_date), e);
                        showsToastAndFinishOnUiThread(R.string.exception_out_of_date);
                    } catch (TangoErrorException e) {
                        Log.e(TAG,getString(R.string.exception_tango_error),e);
                        showsToastAndFinishOnUiThread(R.string.exception_tango_error);
                    }catch (TangoInvalidException e){
                        Log.e(TAG,getString(R.string.exception_tango_invalid),e);
                        showsToastAndFinishOnUiThread(R.string.exception_tango_invalid);
                    }catch (SecurityException e){
                        Log.e(TAG,getString(R.string.no_permissions),e);
                        showsToastAndFinishOnUiThread(R.string.no_permissions);
                    }
                }

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        synchronized (AreaLearningActivity.this){
                            setupTextViewsAndButtons(mTango);
                        }
                    }
                });
            }
        });
    }

    @Override
    protected void onPause(){
        super.onPause();

        synchronized (this){
            try{
                mTango.disconnect();
            }catch (TangoErrorException e){
                Log.e(TAG,getString(R.string.exception_tango_error),e);
            }
        }
    }

    private void setupTextViewsAndButtons(Tango tango){
        mSaveAdfButton=(Button)findViewById(R.id.save_adf_button);
        mUuidTextView=(TextView)findViewById(R.id.adf_uuid_textview);
        mLocationTextView=(TextView)findViewById(R.id.current_local);

        mSaveAdfButton.setEnabled(true);

        ArrayList<String> fullUuidList;
        fullUuidList=tango.listAreaDescriptions();
        if(fullUuidList.size()==0){
            mUuidTextView.setText(R.string.no_uuid);
        }else {
            mUuidTextView.setText(getString(R.string.number_of_adfs)+fullUuidList.size()
                    +getString(R.string.latest_adf_is)
                    +fullUuidList.get(fullUuidList.size()-1));
        }
    }

    private TangoConfig setTangoConfig(Tango tango){
        TangoConfig config=tango.getConfig(TangoConfig.CONFIG_TYPE_DEFAULT);
        config.putBoolean(TangoConfig.KEY_BOOLEAN_LEARNINGMODE,true);
        config.putBoolean(TangoConfig.KEY_BOOLEAN_MOTIONTRACKING,true);
        config.putBoolean(TangoConfig.KEY_BOOLEAN_AUTORECOVERY,true);

        return config;
    }

    private void startupTango(){
        ArrayList<TangoCoordinateFramePair> framePairs=new ArrayList<TangoCoordinateFramePair>();
        framePairs.add(new TangoCoordinateFramePair(
                TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE,
                TangoPoseData.COORDINATE_FRAME_DEVICE));
        framePairs.add(new TangoCoordinateFramePair(
                TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION,
                TangoPoseData.COORDINATE_FRAME_DEVICE));
        framePairs.add(new TangoCoordinateFramePair(
                TangoPoseData.COORDINATE_FRAME_AREA_DESCRIPTION,
                TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE));

        mTango.connectListener(framePairs, new Tango.OnTangoUpdateListener() {
            @Override
            public void onPoseAvailable(final TangoPoseData pose) {
                mLocationTextView.setText(currentLocal(pose));
            }

            @Override
            public void onXyzIjAvailable(TangoXyzIjData xyzIj){

            }

            @Override
            public void onPointCloudAvailable(TangoPointCloudData xyzij){

            }

            @Override
            public void onTangoEvent(final TangoEvent event){

            }

            @Override
            public void onFrameAvailable(int cameraId){

            }
        });
    }

    private String currentLocal(TangoPoseData pose){
        StringBuilder stringBuilder=new StringBuilder();

        float translation[]=pose.getTranslationAsFloats();
        stringBuilder.append("Position: "+
                translation[0]+", "+translation[1]+", "+translation[2]);

        float orientation[]=pose.getRotationAsFloats();
        stringBuilder.append(". Orientation: "+
                orientation[0]+", "+orientation[1]+", "+
                orientation[2]+", "+orientation[3]);

        return stringBuilder.toString();
    }

    @Override
    public void onAdfNameOk(String name,String uuid){
        saveAdf(name);
    }

    @Override
    public void onAdfNameCancelled(){

    }

    public void saveAdfClicked(View view){
        showSetAdfNameDialog();
    }

    private void saveAdf(String adfName){
        mSaveAdfTask=new SaveAdfTask(this,this,mTango,adfName);
        mSaveAdfTask.execute();
    }

    @Override
    public void onSaveAdfFail(String adfName){
        String toastMessage=String.format(
                getResources().getString(R.string.save_adf_failed_toast_format), adfName);
        Toast.makeText(this,toastMessage,Toast.LENGTH_LONG).show();
        mSaveAdfTask=null;
    }

    @Override
    public void onSaveAdfSuccess(String adfName,String adfUuid){
        String toastMessage=String.format(
                getResources().getString(R.string.save_adf_success_toast_format),adfName,adfUuid);
        Toast.makeText(this,toastMessage,Toast.LENGTH_LONG).show();
        mSaveAdfTask=null;
        finish();
    }

    private void showSetAdfNameDialog(){
        Bundle bundle=new Bundle();
        bundle.putString(TangoAreaDescriptionMetaData.KEY_NAME,"New ADF");
        bundle.putString(TangoAreaDescriptionMetaData.KEY_UUID,"");

        FragmentManager manager=getFragmentManager();
        SetAdfNameDialog setAdfNameDialog=new SetAdfNameDialog();
        setAdfNameDialog.setArguments(bundle);
        setAdfNameDialog.show(manager,"ADFNameDialog");
    }

    private void showsToastAndFinishOnUiThread(final int resId){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(AreaLearningActivity.this,
                        getString(resId),Toast.LENGTH_LONG).show();
                finish();
            }
        });
    }

}
